home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / rpg / crossfir.92 / crossfir / crossfire-0.92.5 / crossedit / App.c next >
C/C++ Source or Header  |  1996-07-24  |  26KB  |  1,073 lines

  1. /*
  2.  *  CrossEdit - game world editor
  3.  *  Copyright (C) 1993 Jarkko Sonninen & Petri Heinila
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  The authors can be reached via e-mail to Jarkko.Sonninen@lut.fi
  20.  *  or Petri.Heinila@lut.fi .
  21.  */
  22.  
  23. #include "Defines.h"
  24. #include "global.h"
  25.  
  26. #include "Ansi.h"
  27. #include "X11.h"
  28.  
  29. #include "CrList.h"
  30. #include "CrFace.h"
  31. #include "CrEdit.h"
  32.  
  33. #include "Edit.h"
  34. #include "Attr.h"
  35. #include "Cnv.h"
  36. #include "Bitmaps.h"
  37. #include "App.h"
  38. #include "debug.h"
  39. #include "util.h"
  40.  
  41. Pixmap *pixmaps;    /* list of pixmaps */
  42. Pixmap *masks;        /* list of masks */
  43. #define E_EDITABLE   (E_MONSTER | E_EXIT | E_TREASURE | E_BACKGROUND | \
  44.                      E_DOOR | E_SPECIAL | E_SHOP | E_NORMAL | E_FALSE_WALL)
  45.  
  46. ArchFlagsRec archFlags[] = {
  47.     { 0, "toggle",    E_EDITABLE },
  48.     { 0, "monster",    E_MONSTER },
  49.     { 0, "exit",    E_EXIT },
  50.     { 0, "treasure",    E_TREASURE },
  51.     { 0, "background",    E_BACKGROUND },
  52.     { 0, "door",    E_DOOR },
  53.     { 0, "special",    E_SPECIAL },
  54.     { 0, "shop",    E_SHOP },
  55.     { 0, "normal",    E_NORMAL },
  56.     { 0, "false wall",    E_FALSE_WALL },
  57.     { 0, "wall",    E_WALL },
  58.     { 0, "equipment",    E_EQUIPMENT },
  59.     { 0, "other",    E_OTHER },
  60.     { 0, "artifact",    E_ARTIFACT },
  61.     { 0, NULL,         0 },
  62. };
  63.  
  64. /*
  65.  * plaah: where to put these ???
  66.  * 0.91.9 - moved to start of file - needed for ReadPixmaps function.
  67.  */
  68. XColor exactcolor, discolor[13];
  69. Colormap colormap;
  70.  
  71.  
  72. /**********************************************************************
  73.  * private
  74.  **********************************************************************/
  75.  
  76. #if 0
  77. static void AbsToCr(App self,String abs)
  78. {
  79.   char mapdir[PATH_MAX+1],path[PATH_MAX+1],*current,*filename;
  80.  
  81.   strcpy(path,abs);
  82.  
  83.   current = strlen(mapdir) + path;
  84.   filename = strrchr(path,'/');
  85.   *filename = 0;
  86.   filename++;
  87.   strcpy(self->path->current,current);
  88.   strcpy(self->path->filename,filename);
  89. }
  90. #endif
  91.  
  92. static void Picks(XtPointer client,String entryPath)
  93. {
  94.   App self = (App)client; 
  95.   String path;
  96.   char mapdir[PATH_MAX+1];
  97.   int i=0;
  98.  
  99.   sprintf(mapdir,"%s/%s",LibDir,MapDir);
  100.   for(path = entryPath; mapdir[i++] == *path++;);
  101.  
  102.   debug1("Picks() %s\n",path);
  103.   AppEditInsert(self,path,Pick);
  104. }
  105.  
  106. static void Walls(XtPointer client,String entryPath)
  107. {
  108.   App self = (App)client;
  109.   String path;
  110.   char mapdir[PATH_MAX+1];
  111.   int i = 0;
  112.  
  113.   sprintf(mapdir,"%s/%s",LibDir,MapDir);
  114.   for(path = entryPath; mapdir[i++] == *path++;);
  115.  
  116.   debug1("Walls() %s\n",path);
  117.   AppEditInsert(self,path,Wall);
  118. }
  119.  
  120. static void Info(XtPointer client,String entryPath)
  121. {
  122.   App self = (App)client; 
  123.  
  124.   CnvBrowseShowFile(self->info,entryPath);
  125. }
  126.  
  127.  
  128. /**********************************************************************
  129.  * select 
  130.  **********************************************************************/
  131.  
  132. /*
  133.  * member: filter archetype list
  134.  * at    : requested archetype
  135.  * return: True, if show out
  136.  */
  137. static Boolean AppArchFilter (App self,archetype * at)
  138. {
  139.     if(self->arch.all) return True;
  140.     return (self->arch.flags & at->editable) ? True : False;
  141. }
  142.  
  143. /*
  144.  * function: give widget head of list
  145.  */
  146. static CrListNode Next(XtPointer client,XtPointer call)
  147. {
  148.   App self = (App)client;
  149.   CrListNode retNode = (CrListNode)call;
  150.   static struct _CrListNode node;
  151.   archetype *at;
  152.  
  153.  
  154.   if(retNode) {
  155.       at = ((archetype *)retNode->ptr)->next;
  156.   } else { /* begin */
  157.       at = first_archetype;
  158.   }
  159.  
  160.   while (at && !AppArchFilter(self,at))
  161.       at = at->next;  
  162.   
  163.   if(at) {
  164.     node.face = at->clone.face; 
  165.     node.name = at->name;
  166.     node.ptr = (XtPointer)at;
  167.     return &node;
  168.   }
  169.   return (CrListNode)NULL;
  170. }
  171.  
  172. /* 
  173.  * create attributes from inventory
  174.  */
  175. static void SelectCb(Widget w,XtPointer client,XtPointer call)
  176. {
  177.     CrListCall ret = (CrListCall)call;
  178.     App self = (App)client;
  179.  
  180.     debug0 ("SelectCb\n");
  181.     /* self->item.wall_map = NULL; */
  182.     AppItemSet (self,NULL,& ((archetype *) ret->node)->clone,0);
  183.     /*
  184.     if(self->attr.isup) {
  185.     AttrSetArch(&self->attr,self->item.at);
  186.     }
  187.     */
  188.     return;
  189. }
  190.  
  191. /**********************************************************************
  192.  * look 
  193.  **********************************************************************/
  194.  
  195. /*
  196.  * function: give widget head of list
  197.  */
  198. static CrListNode lookNext(XtPointer client,XtPointer call)
  199. {
  200.     App self = (App)client;
  201.     CrListNode retNode = (CrListNode)call;
  202.     static struct _CrListNode node;
  203.     object *op = NULL;
  204.  
  205.     if(self->look.edit == NULL) return NULL;
  206.    
  207.     if(retNode) { /* next */
  208.     op = ((object *)retNode->ptr)->below;
  209.     } else {
  210.     /* begin */
  211.     op = MapGetObjectZ(self->look.edit->emap,
  212.                self->look.rect.x,
  213.                self->look.rect.y,0);
  214.     }
  215.     if(op) {
  216.     node.face = op->face; 
  217.     node.name = op->name;
  218.     node.ptr = (XtPointer)op;
  219.         return &node;
  220.     }
  221.     return (CrListNode)NULL;
  222. }
  223.  
  224. /* 
  225.  * 
  226.  */
  227. static void lookSelectCb(Widget w,XtPointer client,XtPointer call)
  228. {
  229.     App self = (App)client;
  230.     CrListCall ret = (CrListCall)call;
  231.     object *ob;
  232.  
  233.     ob = ret->node;
  234.     if (ob->head)
  235.     ob = ob->head;
  236.     if(!self->attr) {
  237.     self->attr = AttrCreate 
  238.         ("attr", self, ob, AttrDescription, GetType(ob), self->look.edit);
  239.     } else {
  240.     AttrChange(self->attr,ob, GetType(ob), self->look.edit);
  241.     }
  242.     return;
  243. }
  244.  
  245. /*
  246.  * callback: insert object to look window
  247.  */
  248. static void lookInsertCb(Widget w,XtPointer client,XtPointer call)
  249. {
  250.     App self = (App)client;
  251.     CrListCall ret = (CrListCall)call;
  252.  
  253.     EditInsert (self->look.edit, 
  254.         self->look.rect.x, self->look.rect.y, ret->index);
  255.     return;
  256. }
  257.  
  258. /*
  259.  * callback: delete object from look window
  260.  */
  261. static void lookDeleteCb(Widget w,XtPointer client,XtPointer call)
  262. {
  263.     App self = (App)client;
  264.     CrListCall ret = (CrListCall)call;
  265.     EditDelete (self->look.edit, self->look.rect.x, self->look.rect.y, 
  266.             ret->index);
  267.     return;
  268. }
  269. /**********************************************************************
  270.  * File-menu
  271.  *   New
  272.  *   Open
  273.  *   CrossFire
  274.  *   Quit
  275.  **********************************************************************/
  276.  
  277. static void AppNewCb(Widget w,XtPointer client,XtPointer call)
  278. {
  279.     App self = (App)client;
  280.     AppEditInsert(self,NULL,Regular);
  281. }
  282.  
  283. #if 0
  284. static void AppClipCb(Widget w,XtPointer client,XtPointer call)
  285. {
  286.     App self = (App)client;
  287.     AppEditInsert(self,NULL,ClipBoard);
  288. }
  289. #endif
  290.  
  291.  
  292. static void AppOpenCb (Widget w, XtPointer client, XtPointer call)
  293. {
  294.     App self = (App)client;
  295.     char path[PATH_MAX+1];
  296.     if(CnvPathSelect(self->path) != CnvPathOk) return;
  297.     sprintf(path,"%s/%s",self->path->current,self->path->filename);
  298.     AppEditInsert(self,path,Regular);
  299. }
  300.  
  301. static void AppCrossfireCb  (Widget w, XtPointer client, XtPointer call)
  302. {
  303.     App self = (App)client;
  304.     int pid;
  305.     char *prog,*arg1;
  306.  
  307.     if(!self->res.cmdCrossfire) {
  308.     CnvNotify("No command defined to *cmdCrossfire:","Continue",NULL);
  309.     return;
  310.     }
  311.     prog = strtok(self->res.cmdCrossfire," \t");
  312.     arg1 = strtok(NULL," \t"); /* kludge for -pix */
  313.     switch(pid = fork()) {
  314.     case -1:
  315.     CnvNotify("Cannot open new process","OK",NULL);
  316.     return;
  317.     case 0: /* child */
  318.     if(execlp(prog,prog,arg1,NULL) == -1) {
  319.         char buf[BUFSIZ];
  320.         sprintf(buf,"cannot execute \"%s\"",self->res.cmdCrossfire);
  321.         CnvWarn(self->shell,buf);
  322.         exit(0);
  323.     }
  324.     default: /* parent */
  325.     debug2("CbMainCrossfire() %d %s started\n",pid,self->res.cmdCrossfire);
  326.     return;
  327.     }
  328. }
  329.  
  330. /*
  331.  *
  332.  */
  333. static void AppQuitCb (Widget w, XtPointer client, XtPointer call)
  334. {
  335.     App self = (App)client;
  336.  
  337.     AppDestroy(self);
  338.     XtDestroyApplicationContext (XtWidgetToApplicationContext (w));
  339.     exit (0);
  340. }
  341.  
  342. /*
  343.  * file-menu definition
  344.  */
  345. static CnvMenuRec fileMenu[] = {
  346.     {"new"      ,AppNewCb},
  347.     {"open"     ,AppOpenCb},
  348. #if 0
  349.     {"clipboard",AppClipCb}, 
  350. #endif
  351.     {"-----"    ,NULL},
  352.     {"crossfire",AppCrossfireCb},
  353.     {"-----"    ,NULL},
  354.     {"quit"     ,AppQuitCb},
  355.     {""         ,NULL}
  356. }; 
  357.  
  358. /**********************************************************************
  359.  * toggle-menu
  360.  **********************************************************************/
  361.  
  362. static void dirtyfixscrollbar (Widget w) {
  363.     Widget s = XtParent (w);
  364.     XawViewportSetCoordinates (s, 0, 0);
  365.     /* undocumented function */
  366. }
  367.  
  368.  
  369. static void ToggleFlagCb(Widget w, XtPointer client, XtPointer call)
  370. {
  371.     App self = (App)client;
  372.     int i;
  373.  
  374.     for (i = 0; archFlags[i].name; i++) {
  375.     if (archFlags[i].w == w) {
  376.         self->arch.flags ^= archFlags[i].flags;
  377.         break;
  378.     }
  379.     }
  380.     dirtyfixscrollbar (self->arch.w);
  381.     XtVaSetValues (self->arch.w, XtNpackage, self, NULL);
  382.     for (i = 0; archFlags[i].name; i++) {
  383.     XtVaSetValues
  384.         (archFlags[i].w,
  385.          XtNleftBitmap, 
  386.          (self->arch.flags & archFlags[i].flags) ? bitmaps.mark : None,
  387.          NULL);
  388.     }
  389.     return;
  390. }
  391.  
  392.  
  393. static void ToggleAllCb(Widget w, XtPointer client, XtPointer call)
  394. {
  395.     App self = (App)client;
  396.  
  397.     self->arch.all = !self->arch.all;
  398.     dirtyfixscrollbar (self->arch.w);
  399.  
  400.     XtVaSetValues (self->arch.w, XtNpackage, self, NULL);
  401.     XtVaSetValues(w,
  402.           XtNleftBitmap, 
  403.           self->arch.all ? bitmaps.mark : None,
  404.           NULL);
  405. }
  406.  
  407. static void ToggleClipCb(Widget w, XtPointer client, XtPointer call)
  408. {
  409.   App self = (App)client;
  410.  
  411.   self->clipon = !self->clipon;
  412.   XtVaSetValues(w,
  413.         XtNleftBitmap, 
  414.         self->clipon ? bitmaps.mark : None,
  415.         NULL);
  416.   if(self->clipon)
  417.       XtPopup(self->clip->shell,XtGrabNone);
  418.   else
  419.       XtPopdown(self->clip->shell);
  420. }
  421.  
  422. static void AppToggleMenu(App self,String name,Widget parent)
  423. {
  424.     Widget shell,entry;
  425.     int i;
  426.  
  427.     shell = XtVaCreatePopupShell
  428.     (name,simpleMenuWidgetClass,parent,
  429.      NULL);
  430.     
  431.     entry = XtVaCreateManagedWidget
  432.     ("all",smeBSBObjectClass,shell,
  433.      XtNleftBitmap,
  434.      self->arch.all ? bitmaps.mark : None,
  435.      NULL);
  436.     XtAddCallback(entry,XtNcallback,ToggleAllCb,(XtPointer)self);
  437.     
  438.     for (i = 0; archFlags[i].name; i++) {
  439.     archFlags[i].w = XtVaCreateManagedWidget
  440.         (archFlags[i].name, smeBSBObjectClass,shell,
  441.          XtNleftBitmap,
  442.          (self->arch.flags  & archFlags[i].flags) ? 
  443.          bitmaps.mark : None,
  444.          NULL);
  445.     XtAddCallback
  446.         (archFlags[i].w,XtNcallback,ToggleFlagCb,(XtPointer)self);
  447.     }
  448.  
  449.     XtVaCreateManagedWidget ("line", smeLineObjectClass, shell, NULL);
  450.     entry = XtVaCreateManagedWidget
  451.     ("clipboard",smeBSBObjectClass,shell,
  452.      XtNleftBitmap,
  453.      self->clipon ? bitmaps.mark : None,
  454.      NULL);
  455.     XtAddCallback(entry,XtNcallback,ToggleClipCb,(XtPointer)self);
  456. }
  457.  
  458. /**********************************************************************
  459.  * editMenu callbacks (cut,copy,paste,...)
  460.  **********************************************************************/
  461.  
  462. /* 
  463.  * callback: Cut
  464.  */
  465. static void CutCb (Widget w, XtPointer client, XtPointer call)
  466. {
  467.     App self = (App)client;
  468.     XRectangle rect;
  469.  
  470.     debug0 ("AppCutCb()\n");
  471.     if(!self->look.edit) {
  472.     CnvNotify("Select area to Cut","Continue",NULL);
  473.     return;
  474.     }
  475.     EditResizeScroll(self->clip,self->look.rect.width,
  476.              self->look.rect.height,0,0);
  477.     /*
  478.     EditCopyRectangle(self->look.edit,self->clip,EditRectAll,
  479.               self->look.rect.x,self->look.rect.y);
  480.               */
  481.     rect.x = rect.y = 0;
  482.     rect.width = self->look.rect.width;
  483.     rect.height = self->look.rect.height;
  484.     EditWipeRectangle(self->clip,rect);
  485.     EditCopyRectangle(self->clip,self->look.edit,self->look.rect,0,0);
  486.     EditWipeRectangle(self->look.edit,self->look.rect);
  487.  
  488.     EditModified(self->look.edit);
  489.     CrEditRefresh(self->look.edit->w,self->look.rect);
  490.     AppSelectUnset(self);
  491. }
  492.  
  493. /* 
  494.  * callback: Copy
  495.  */
  496. static void CopyCb (Widget w, XtPointer client, XtPointer call)
  497. {
  498.     App self = (App)client;
  499.     XRectangle rect;
  500.     
  501.     debug0 ("AppCopyCb()\n");
  502.     if(!self->look.edit) {
  503.     CnvNotify("Select area to Copy","Continue",NULL);
  504.     return;
  505.     }
  506.     EditResizeScroll(self->clip,self->look.rect.width,
  507.              self->look.rect.height,0,0);
  508.     rect.x = rect.y = 0;
  509.     rect.width = self->look.rect.width;
  510.     rect.height = self->look.rect.height;
  511.     EditWipeRectangle(self->clip,rect);
  512.     EditCopyRectangle(self->clip,self->look.edit,self->look.rect,0,0);
  513.  
  514.     AppSelectUnset(self);
  515. }
  516.  
  517. /* 
  518.  * callback: Paste
  519.  */
  520. static void PasteCb (Widget w, XtPointer client, XtPointer call)
  521. {
  522.     App self = (App)client;
  523.    
  524.     debug0 ("AppPasteCb()\n");
  525.  
  526.     if(!self->look.edit) {
  527.     CnvNotify("Select point to Paste","Continue",NULL);
  528.     return;
  529.     }
  530.     EditCopyRectangle(self->look.edit,self->clip,EditRectAll,
  531.               self->look.rect.x,self->look.rect.y);
  532.  
  533.     EditModified(self->look.edit);
  534.  
  535.     AppSelectUnset(self);
  536. }
  537.  
  538. /* 
  539.  * callback: Fill
  540.  */
  541. static void FillCb (Widget w, XtPointer client, XtPointer call)
  542. {
  543.     App self = (App)client;
  544.     
  545.     debug0 ("AppFillCb()\n");
  546.     if(!self->look.edit) {
  547.     CnvNotify("Select point to Fill","Continue",NULL);
  548.     return;
  549.     }
  550.     EditPerformFill(self->look.edit,self->look.rect.x,self->look.rect.y);
  551.     EditModified(self->look.edit);
  552.     AppSelectUnset(self);
  553. }
  554.  
  555. /* 
  556.  * callback: Box
  557.  */
  558. static void BoxCb (Widget w, XtPointer client, XtPointer call)
  559. {
  560.     App self = (App)client;
  561.  
  562.     debug0 ("AppBoxCb()\n");
  563.     if(!self->look.edit) {
  564.     CnvNotify("Select area to fill","Continue",NULL);
  565.     return;
  566.     }
  567.     EditFillRectangle(self->look.edit, self->look.rect);
  568.     EditModified(self->look.edit);
  569.     AppSelectUnset(self);
  570. }
  571.  
  572. /* 
  573.  * callback: Wipe
  574.  */
  575. static void WipeCb (Widget w, XtPointer client, XtPointer call)
  576. {
  577.     App self = (App)client;
  578.     
  579.     debug0 ("AppWipeCb()\n");
  580.     if(!self->look.edit) {
  581.     CnvNotify("Select area to Wipe","Continue",NULL);
  582.     return;
  583.     }
  584.     
  585.     EditShaveRectangle(self->look.edit, self->look.rect);
  586.     EditModified(self->look.edit);
  587.     AppSelectUnset(self);
  588. }
  589.  
  590. /*
  591.  * menu definition
  592.  */
  593. static CnvMenuRec editMenu[] = {
  594.     {"cut"  ,CutCb},
  595.     {"copy" ,CopyCb},
  596.     {"paste",PasteCb},
  597.     {"-----",NULL},
  598.     {"fill" ,FillCb},
  599.     {"box" ,BoxCb},
  600.     {"wipe" ,WipeCb},
  601.     {"",     NULL}
  602. }; 
  603.  
  604. /**********************************************************************
  605.  * layout 
  606.  **********************************************************************/
  607.  
  608. /*
  609.  * member: create application window layout 
  610.  */
  611. static void Layout(App self)
  612. {
  613.     Widget pane, box,use,view;
  614.     char path[PATH_MAX+1];
  615.     
  616.     /*** vertical Pane of widgets ***/
  617.     pane = XtCreateManagedWidget 
  618.     ("pane", panedWidgetClass, self->shell, 
  619.      NULL, 0);
  620.     
  621.     /*** menubar ***/
  622.     box = XtVaCreateManagedWidget 
  623.     ("box", boxWidgetClass, pane,
  624.      XtNorientation, XtorientHorizontal,
  625.      NULL);
  626.     use = XtVaCreateManagedWidget 
  627.       ("fileButton",menuButtonWidgetClass, box,
  628.        XtNmenuName,"appFileMenu",
  629.        NULL);
  630.     CnvMenu("appFileMenu",use,fileMenu,(XtPointer)self);
  631.  
  632.     use = XtVaCreateManagedWidget 
  633.     ("infoButton",menuButtonWidgetClass, box,
  634.      XtNmenuName,"info",
  635.      NULL);
  636.     sprintf(path,"%s/%s",LibDir,"doc");
  637.     self->infof = CnvFilesCreate("info",use,Info,(XtPointer)self,path);
  638.     
  639.     /*** look ***/
  640.     self->look.info = XtVaCreateManagedWidget
  641.     ("info",labelWidgetClass,pane,
  642.      NULL);
  643.  
  644.     view = XtVaCreateManagedWidget 
  645.     ("view", viewportWidgetClass,pane,
  646.      NULL);
  647.     self->look.w = XtVaCreateManagedWidget 
  648.     ("cross",crListWidgetClass,view, 
  649.      XtNpackage, self,
  650.      XtNnext, lookNext,
  651.      NULL);
  652.     XtAddCallback(self->look.w,XtNinsertCallback,lookInsertCb,
  653.           (XtPointer)self);
  654.     XtAddCallback(self->look.w,XtNselectCallback,lookSelectCb,
  655.           (XtPointer)self);
  656.     XtAddCallback(self->look.w,XtNdeleteCallback,lookDeleteCb,
  657.           (XtPointer)self);
  658.     
  659.     /*** arch ***/
  660.     box = XtVaCreateManagedWidget 
  661.     ("box", boxWidgetClass, pane, 
  662.      XtNorientation, XtorientHorizontal,
  663.      NULL);
  664.     use = XtVaCreateManagedWidget 
  665.     ("archButton",menuButtonWidgetClass, box,
  666.      XtNmenuName,"toggle",
  667.      NULL);
  668.     AppToggleMenu(self,"toggle",use);
  669.     use = XtVaCreateManagedWidget 
  670.     ("pickButton",menuButtonWidgetClass, box,
  671.      XtNmenuName,"picks",
  672.      NULL);
  673.     sprintf(path,"%s/%s/%s",LibDir,MapDir,"editor/picks");
  674.     self->picks = CnvFilesCreate("picks",use,Picks,(XtPointer)self,path);
  675.     use = XtVaCreateManagedWidget 
  676.       ("wallButton",menuButtonWidgetClass, box,
  677.        NULL);
  678.     sprintf(path,"%s/%s/%s",LibDir,MapDir,"editor/walls");
  679.     self->walls = CnvFilesCreate("menu",use,Walls,(XtPointer)self,path);
  680.  
  681.     use = XtVaCreateManagedWidget 
  682.     ("arch", viewportWidgetClass, pane, 
  683.      NULL);
  684.     self->arch.w = XtVaCreateManagedWidget 
  685.     ("cross",crListWidgetClass,use, 
  686.      XtNpackage, self,
  687.      XtNnext, Next,
  688.      NULL);
  689.     XtAddCallback(self->arch.w,XtNselectCallback,SelectCb,(XtPointer)self);
  690. #if 0
  691.     XtAddCallback(self->arch.w,XtNdeleteCallback,SelectCb,(XtPointer)self);
  692.     XtAddCallback(self->arch.w,XtNinsertCallback,SelectCb,(XtPointer)self);
  693. #endif
  694.  
  695.     /*** item ***/
  696.     box = XtVaCreateManagedWidget 
  697.     ("item", formWidgetClass, pane, 
  698.      XtNorientation, XtorientVertical,
  699.      NULL);
  700.     self->item.name = XtVaCreateManagedWidget
  701.     ("name",labelWidgetClass,box,
  702.      NULL);
  703.     self->item.face = XtVaCreateManagedWidget
  704.     ("face",crFaceWidgetClass,box,
  705.      XtNfromVert, self->item.name,
  706.      NULL);
  707.  
  708.     /*** used on other places ***/
  709.     self->look.menu = CnvMenu        /* cut,copy,paste-menu on editors */
  710.     ("mapEdit",self->shell,editMenu,(XtPointer)self);
  711.     self->info = CnvBrowseCreate("infoFile",self->shell, NULL);
  712.     /* browsing text */
  713. }
  714.  
  715. /**********************************************************************
  716.  * public
  717.  **********************************************************************/
  718.  
  719. /*
  720.  * member       : create one application main window
  721.  * appCon       : on self Xt application context
  722.  * displayString: on self display
  723.  * argc         : number of command line params
  724.  * argv         : list of command line params
  725.  */
  726. App AppCreate(XtAppContext appCon,
  727.           String displayString,
  728.           XtResource resources[],
  729.           Cardinal resourcesNum,
  730.           XrmOptionDescRec *options,
  731.           Cardinal optionsNum,
  732.           int *argc,
  733.           char *argv[])
  734. {
  735.     char buf[BUFSIZ];
  736.     char path[PATH_MAX+1];
  737.     App self;
  738.  
  739.  
  740.     /*** initialize ***/
  741.     self = (App)XtMalloc(sizeof(struct _App));
  742.     memset(self,0,sizeof(struct _App));
  743.     self->display = XtOpenDisplay
  744.     (appCon,
  745.      NULL,NULL,AppClass,
  746.      options,optionsNum,
  747.      argc,argv);
  748.     if(!self->display) {
  749.     sprintf(buf,"Cannot open display %s",displayString);
  750.     XtAppError(appCon,buf);
  751.     exit(EXIT_FAILURE);
  752.     }
  753.  
  754.     BitmapsCreate(self->display); 
  755.     self->shell = XtVaAppCreateShell
  756.     (NULL,AppClass,
  757.      applicationShellWidgetClass,
  758.      self->display,
  759.      XtNtitle,AppClass,
  760.      XtNiconName,AppClass,
  761.      XtNiconPixmap,bitmaps.edit,
  762.      NULL);
  763.     self->attr = NULL;
  764.     self->edit = NULL;
  765.     self->clip = NULL;
  766.     self->clipon = 0;
  767.     self->path = NULL;
  768.     self->look.edit = NULL;
  769.     self->arch.flags= E_EDITABLE;
  770.     self->arch.all = 0;
  771.     self->item.clone = NULL;
  772.     self->item.wall_map = NULL;
  773.     self->item.edit = NULL;
  774.  
  775.     /*** ***/
  776.     XtGetApplicationResources 
  777.     (self->shell, 
  778.      (XtPointer) & self->res,
  779.      resources, resourcesNum, 
  780.      NULL, 0);
  781.  
  782.     /*** images & colors ***/
  783.     InitializeColors(XtDisplay(self->shell));
  784.  
  785.     use_pixmaps = self->res.usePixmaps; /* kludge */
  786. #ifdef Xpm_Pix
  787.     color_pix = self->res.useColorPixmaps; /* kludge, do not use */
  788.     if (color_pix) use_pixmaps=0;
  789. #else
  790.     color_pix = 0;
  791. #endif
  792.  
  793.     CnvInitialize(self->shell);
  794.  
  795.     if(color_pix) {
  796.     if (ReadPixmaps(self->display, &pixmaps, &masks, &colormap)) {
  797.         /* We really should do something better than this */
  798.         fprintf(stderr,"Not enough space in colormap - switch colormap.\n");
  799. /*        exit(1);*/
  800.     }
  801.     } else {
  802.     if (use_pixmaps)
  803.         pixmaps = ReadBitmaps(self->display);
  804.     else if (!check_font_path(XtDisplay (self->shell))) {
  805.         fprintf(stderr, "Trying to fix fontpath...\n");
  806.         fflush(stderr);
  807.         set_font_path (XtDisplay (self->shell), FONTDIR);
  808.         if (!check_font_path(XtDisplay (self->shell))) {
  809.         LOG(llevError,"Failed to set fontpath.\n");
  810.         }
  811.     }
  812.     }
  813.     XtVaSetValues(self->shell, XtNcolormap, colormap, NULL);
  814.  
  815.     /*** creating ***/
  816.     sprintf(path,"%s/%s",LibDir,MapDir);
  817.     self->path = CnvPathCreate("fileSelect",path, "");
  818.     self->clip = EditCreate(self,ClipBoard,"/Clipboard"); /* separate from */
  819.     Layout(self);
  820.     XtRealizeWidget (self->shell);
  821.     XtRealizeWidget(self->clip->shell);
  822.     AppUpdate(self);
  823.     return self;
  824. }
  825.  
  826. /*
  827.  * member: vanish application
  828.  */
  829. void AppDestroy(App self)
  830. {
  831.     Edit edit;
  832.  
  833.     debug0("AppDestroy()");
  834.     /*
  835.     XUnloadFont (XtDisplay (self->shell), self->font);
  836.     XtReleaseGC (self->shell, self->gc);
  837.     XtReleaseGC (self->shell, self->text_gc);
  838.     */
  839.  
  840.     if(self->attr) {
  841.     AttrDestroy(self->attr);
  842.     }
  843.     self->attr = NULL;
  844.     for(edit = self->edit; edit ;edit = edit->next)
  845.     EditDestroy(edit);
  846. }
  847.  
  848. /*
  849.  *
  850.  *Description:
  851.  * update all things 
  852.  */
  853. void AppUpdate(App self)
  854. {
  855.     char buf[BUFSIZ];
  856.     object *obj;
  857.  
  858.     debug0 ("AppUpdate()\n");
  859.     /*** look ***/
  860.     XtVaSetValues (self->look.w, XtNpackage, self, NULL); /*** pseudo ***/
  861.     if(self->look.edit) {
  862.     sprintf(buf,"Look: %dx%d+%d+%d",
  863.         self->look.rect.width,
  864.         self->look.rect.height,
  865.         self->look.rect.x,
  866.         self->look.rect.y);
  867.  
  868. #if 0
  869.     if (self->attr) {
  870.         object *ob = MapGetObjectZ (self->look.edit->emap, 
  871.                     self->look.rect.x, 
  872.                     self->look.rect.y,0);
  873.         AttrChange(self->attr, ob, GetType(ob));
  874.     }
  875. #endif
  876.     } else {
  877.     sprintf(buf,"Look: (no map)");
  878.     }
  879.     XtVaSetValues(self->look.info,
  880.           XtNlabel,buf,
  881.           NULL);
  882.  
  883.     /*** item ***/
  884.     if((obj = AppItemGetObject(self)) && obj->arch) {
  885.     if(AppItemGetMap(self)) {
  886.         XtVaSetValues(self->item.name,
  887.               XtNlabel,"(auto-joining)",
  888.               NULL);
  889.         if((obj = get_map_ob(AppItemGetMap(self),0,
  890.                 AppItemGetWall(self)))) {
  891.         XtVaSetValues(self->item.face,
  892.                   XtNobject,
  893.                   obj,
  894.                   NULL);
  895.         } else {
  896.         debug0("App-No object to show\n");
  897.         }
  898.     } else {
  899.         XtVaSetValues(self->item.name,
  900.               XtNlabel,AppItemGetObject(self)->arch->name,
  901.               NULL);
  902.         XtVaSetValues(self->item.face,
  903.               XtNobject, AppItemGetObject(self),
  904.               NULL);
  905.     }
  906.     } else {
  907.     XtVaSetValues(self->item.name,
  908.               XtNlabel, "Not Selected",
  909.               NULL);
  910.     XtVaSetValues(self->item.face,
  911.               XtNobject,NULL,
  912.               NULL);
  913.     }
  914. }
  915.  
  916. /*
  917.  *
  918.  */
  919. void AppSelectSet(App self,Edit edit,XRectangle rect)
  920. {
  921.     if(edit == NULL) {
  922.     debug0("AppSelectSet() WARN try set NULL Edit\n");
  923.     return;
  924.     }
  925.     if(self->look.edit && self->look.edit != edit)
  926.     CrEditBorderOff(self->look.edit->w);
  927.     self->look.edit = edit;
  928.     self->look.rect = rect;
  929.     AppUpdate(self);
  930. }
  931.  
  932. /*
  933.  *
  934.  */
  935. void AppSelectUnset(App self)
  936. {
  937.     if (self->look.edit == NULL) return;
  938.     CrEditBorderOff(self->look.edit->w);
  939.     CrEditRefresh(self->look.edit->w,self->look.rect);
  940.     self->look.edit = NULL;
  941.     AppUpdate(self);
  942. }
  943.  
  944. /* 
  945.  * member : item - window to show inserted archetype
  946.  * edit   : object is selectted from self map, NULL if from
  947.  *          main window or no selection
  948.  * obj    : self object is selected to cloning
  949.  * wallSet:
  950.  */
  951. void AppItemSet (App self, Edit edit,object *obj,int wallSet)
  952. {
  953.     self->item.edit = NULL;
  954.     self->item.wall_map = NULL;
  955.     self->item.clone = NULL;
  956.     self->item.wall_set = AppItemNoWall;
  957.  
  958.     if(edit) {             /* from map */
  959.     self->item.edit = edit;
  960.     if(wallSet > AppItemNoWall) { /* wall map */
  961.         self->item.wall_map = edit->emap;
  962.         self->item.wall_set = wallSet;
  963.         self->item.clone = get_map_ob(edit->emap,0,wallSet);
  964.     } else {           /* other */
  965.         self->item.clone = obj;
  966.     }
  967.     } else if(obj) {               /* from main window */
  968.     self->item.clone = obj;
  969.     } else {
  970.     /* debug("AppItemSet() strange selection\n"); */
  971. /*    return;*/
  972.     }
  973.     AppUpdate(self);
  974. }
  975.  
  976.  
  977. char PixelFromAlias(char *name) {
  978.   int i;
  979.   for(i=0;i<13;i++)
  980.     if(!strcmp(name,colorname[i][0]))
  981.       return discolor[i].pixel;
  982.   LOG(llevError,"Unknown color: %s\n",name);
  983.   return 0;
  984. }
  985.  
  986. void  InitializeColors (Display *dpy)
  987. {
  988.     int i;
  989.     int private=0;
  990.  
  991.     colormap = DefaultColormap (dpy, DefaultScreen (dpy));
  992.     for (i = 0; i < 13; i++) {
  993.     if (!XLookupColor (dpy, colormap, colorname[i][1], &exactcolor,
  994.         &discolor[i])) {
  995.         die ("Can't find color.");
  996.     }
  997.     if (!XAllocColor (dpy, colormap, &discolor[i])) {
  998.         if (!private) {
  999.         LOG(llevDebug,"Switching to a private colormap.\n");
  1000.         colormap=XCopyColormapAndFree(dpy, colormap);
  1001.         private=1;
  1002.         if (!XAllocColor (dpy, colormap, &discolor[i]))
  1003.             die ("Can't allocate colors.");
  1004.         }
  1005.         else 
  1006.         die ("Can't allocate colors.");
  1007.     }
  1008.     }
  1009. }
  1010.  
  1011. /*
  1012.  * member: add editor
  1013.  */
  1014. Edit AppEditInsert(App self,String path,EditType type)
  1015. {
  1016.     Edit edit;
  1017.     char buf[BUFSIZ];
  1018.  
  1019.     /*** check if exist ***/
  1020.     if(has_been_loaded (path)) {
  1021.     sprintf(buf,"%s aready in memory",path);
  1022.     CnvNotify(buf,"Continue",NULL);
  1023.     return NULL;
  1024.     }
  1025.     /*** create new one ***/
  1026.     if((edit = EditCreate(self,type,path)) == NULL) {
  1027.     return NULL;
  1028.     }
  1029.     AppEditAttach(self,edit);
  1030.     return edit;
  1031. }
  1032.  
  1033. /*
  1034.  * attach Edit to App environment
  1035.  */
  1036. void AppEditAttach(App self,Edit edit)
  1037. {
  1038.     debug1("AppEditAttach() %s\n",EditGetPath(edit));
  1039.     /*** attach edit to list ***/
  1040.     edit->next = self->edit;
  1041.     self->edit = edit;
  1042.  
  1043.     edit->app = self;
  1044. }
  1045.  
  1046. /*
  1047.  * deattach edit from list
  1048.  */
  1049. void AppEditDeattach(App self,Edit edit)
  1050. {
  1051.     Edit oldPrev,old;
  1052.     debug1("AppEditdeattach() %s\n",EditGetPath(edit));
  1053.  
  1054.     oldPrev = old = NULL;
  1055.     for(old = self->edit;
  1056.     old && old != edit;
  1057.     oldPrev = old, old = old->next)
  1058.     debug1("AppEditDeattach() %s\n",EditGetPath(old));
  1059.  
  1060.     if(!old) {
  1061.     CnvWarn(self->shell,"Trying delete unlinked edit");
  1062.     } else {
  1063.     if(!oldPrev) { /* first */
  1064.         self->edit = old->next;
  1065.     } else {
  1066.         oldPrev->next = old->next;
  1067.     }
  1068.     }
  1069.     /* edit->app = NULL; */
  1070. }
  1071.  
  1072. /*** end of App.c ***/
  1073.